using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace Shrapnel
{
	public partial class View 
	{
		/// <summary>
		/// View information at the start of zooming
		/// </summary>
		private InitialViewState zoomingStartInfo;

		/// <summary>
		/// Minimum zoom factor. This limits the amount of zoom in. You can't zoom in further than this.
		/// </summary>
		private float minimumZoomFactor = 1.0f / 4.0f;

		/// <summary>
		/// Zoom sensitivity, higher values result in faster zooming.
		/// </summary>
		private float zoomSensitivity = 0.006f;

		/// <summary>
		/// Minimum zoom factor. This limits the amount of zoom in. You can't zoom in further than this.
		/// </summary>
		public float MinimumZoomFactor
		{
			get { return minimumZoomFactor; }
			set { minimumZoomFactor = value; }
		}

		/// <summary>
		/// Zoom sensitivity, higher values result in faster zooming.
		/// </summary>
		public float ZoomSensitivity
		{
			get { return zoomSensitivity; }
			set { zoomSensitivity = value; }
		}

        /// <summary>
        /// Adjust our view to have ALL items fit in 95% of our view. This doesn't do anything
        /// when no items exist.
        /// </summary>
        public void ZoomAllInView()
        {
            List<Element> all = new List<Element>();

            foreach (Layer layer in layers)
            {
                all.AddRange(layer);
            }

            ZoomExtents(all);
        }

        /// <summary>
        /// Adjust our view to have all selected items fit in 95% of our view. This doesn't do 
        /// anything when nothing is selected.
        /// </summary>
        public void ZoomSelectionInView()
        {
            List<Cable> affectedCables = new List<Cable>();

            List<Element> selectionList = new List<Element>(selection);
            ZoomExtents(selectionList);
        }

		private void OnZoomingStart(Point mousePosition)
		{
			zoomingStartInfo.viewState = new ViewState(viewState);
			zoomingStartInfo.mousePosition = mousePosition;
		}

		private void OnZoomingStop(Point mousePosition)
		{

		}

		private void OnZoomingTick(Point mousePosition)
		{
			float zoomScale = (1.0f + (mousePosition.Y - zoomingStartInfo.mousePosition.Y) * zoomSensitivity);

			// make sure our zoom wont get below a certain minimum
			if (zoomingStartInfo.viewState.ZoomFactor * zoomScale < minimumZoomFactor)
			{
				zoomScale = minimumZoomFactor / zoomingStartInfo.viewState.ZoomFactor;
			}

			viewState.ZoomFactor = zoomScale * zoomingStartInfo.viewState.ZoomFactor;

			PointF clickWorldPos = new PointF(
				zoomingStartInfo.mousePosition.X - zoomingStartInfo.viewState.Offset.X,
				zoomingStartInfo.mousePosition.Y - zoomingStartInfo.viewState.Offset.Y);

			clickWorldPos.X /= zoomingStartInfo.viewState.ZoomFactor;
			clickWorldPos.Y /= zoomingStartInfo.viewState.ZoomFactor;

			PointF newOffset = clickWorldPos;

			newOffset.X *= zoomingStartInfo.viewState.ZoomFactor * (1.0f - zoomScale);
			newOffset.Y *= zoomingStartInfo.viewState.ZoomFactor * (1.0f - zoomScale);
			newOffset.X += zoomingStartInfo.viewState.Offset.X;
			newOffset.Y += zoomingStartInfo.viewState.Offset.Y;

			viewState.Offset = newOffset;

			Invalidate();
		}
	}
}
